package com.zhonghui.modlules.order.eshopService.Ipml;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.eshop.apiCode.BusinessException;
import com.eshop.apiCode.EshopException;
import com.eshop.service.Impl.BaseServiceImpl;
import com.zhonghui.common.eshopDomain.ShopUser;
import com.zhonghui.common.eshopDomain.StorePink;
import com.zhonghui.common.eshopDozer.config.IGenerator;
import com.zhonghui.common.eshopEnum.*;
import com.zhonghui.common.eshopEvent.TemplateBean;
import com.zhonghui.common.eshopEvent.TemplateEvent;
import com.zhonghui.common.eshopEvent.TemplateListenEnum;
import com.zhonghui.common.eshopService.StoreBargainUserService;
import com.zhonghui.common.eshopService.StorePinkService;
import com.zhonghui.modlules.cart.eshopVo.StoreCartQueryVo;
import com.zhonghui.modlules.order.eshopDomain.EshopExpress;
import com.zhonghui.modlules.order.eshopDomain.StoreOrder;
import com.zhonghui.modlules.order.eshopDto.StatusDto;
import com.zhonghui.modlules.order.eshopMapper.StoreOrderMapper;
import com.zhonghui.modlules.order.eshopService.ExpressService;
import com.zhonghui.modlules.order.eshopService.StoreOrderCartInfoService;
import com.zhonghui.modlules.order.eshopService.StoreOrderService;
import com.zhonghui.modlules.order.eshopService.StoreOrderStatusService;
import com.zhonghui.modlules.order.eshopVo.StoreOrderCartInfo;
import com.zhonghui.modlules.order.eshopVo.StoreOrderQueryVo;
import com.zhonghui.modlules.product.eshopDomain.StoreProductReply;
import com.zhonghui.modlules.product.eshopService.StoreProductReplyService;
import com.zhonghui.modlules.user.eshopService.UserBillService;
import com.zhonghui.modlules.user.eshopService.UserService;
import com.zhonghui.modlules.user.eshopVo.UserQueryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Transactional(
        propagation = Propagation.REQUIRED,
        rollbackFor = {Exception.class}
)
public class StoreOrderServiceImpl extends BaseServiceImpl<StoreOrderMapper, StoreOrder> implements StoreOrderService {
    @Autowired
    private IGenerator generator;
    @Autowired
    private StoreOrderMapper yxStoreOrderMapper;
    @Autowired
    private StorePinkService pinkService;
    @Autowired
    private StoreOrderCartInfoService orderCartInfoService;
    @Autowired
    private StoreProductReplyService productReplyService;
    @Autowired
    private StoreOrderStatusService orderStatusService;
    @Autowired
    private StoreOrderCartInfoService storeOrderCartInfoService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserBillService billService;
    @Autowired
    private ApplicationEventPublisher publisher;
    @Autowired
    private StoreBargainUserService storeBargainUserService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private ExpressService expressService;

    public StoreOrderQueryVo getOrderInfo(String unique, Long uid) {
        LambdaQueryWrapper<StoreOrder> wrapper = new LambdaQueryWrapper();
        wrapper.and((i) -> {
            LambdaQueryWrapper var10000 = i.eq(StoreOrder::getOrderId, unique)
                    .or().eq(StoreOrder::getUnique, unique)
                    .or().eq(StoreOrder::getExtendOrderId, unique);
        });
        if (uid != null) {
            wrapper.eq(StoreOrder::getUid, uid);
        }

        return (StoreOrderQueryVo)this.generator.convert(this.yxStoreOrderMapper.selectOne(wrapper), StoreOrderQueryVo.class);
    }

    public void orderApplyRefund(String explain, String Img, String text, String orderId, Long uid) {
        StoreOrderQueryVo order = this.getOrderInfo(orderId, uid);
        if (order == null) {
            throw new EshopException("订单不存在");
        } else if (OrderInfoEnum.REFUND_STATUS_2.getValue().equals(order.getRefundStatus())) {
            throw new EshopException("订单已退款");
        } else if (OrderInfoEnum.REFUND_STATUS_1.getValue().equals(order.getRefundStatus())) {
            throw new EshopException("正在申请退款中");
        } else if (OrderInfoEnum.STATUS_1.getValue().equals(order.getStatus())) {
            throw new EshopException("订单当前无法退款");
        } else {
            StoreOrder storeOrder = new StoreOrder();
            storeOrder.setRefundStatus(OrderInfoEnum.REFUND_STATUS_1.getValue());
            storeOrder.setRefundReasonTime(new Date());
            storeOrder.setRefundReasonWapExplain(explain);
            storeOrder.setRefundReasonWapImg(Img);
            storeOrder.setRefundReasonWap(text);
            storeOrder.setId(order.getId());
            this.yxStoreOrderMapper.updateById(storeOrder);
            this.orderStatusService.create(order.getId(), OrderLogEnum.REFUND_ORDER_APPLY.getValue(), "用户申请退款，原因：" + text);
            TemplateBean templateBean = TemplateBean.builder().orderId(order.getOrderId()).price(order.getPayPrice().toString()).uid(order.getUid()).templateType(TemplateListenEnum.TYPE_9.getValue()).time(DateUtil.formatTime(new Date())).build();
            this.publisher.publishEvent(new TemplateEvent(this, templateBean));
        }
    }

    public void orderDelivery(String orderId, String deliveryId, String deliveryName, String deliveryType) {
        StoreOrderQueryVo orderQueryVo = this.getOrderInfo(orderId, (Long)null);
        if (ObjectUtil.isNull(orderQueryVo)) {
            throw new EshopException("订单不存在");
        } else if (OrderInfoEnum.STATUS_0.getValue().equals(orderQueryVo.getStatus()) && !OrderInfoEnum.PAY_STATUS_0.getValue().equals(orderQueryVo.getPaid())) {
            LambdaQueryWrapper<EshopExpress> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq( EshopExpress::getName, deliveryName );
            EshopExpress expressQueryVo = (EshopExpress)this.expressService.getOne(wrapper);
            if (ObjectUtil.isNull(expressQueryVo)) {
                throw new EshopException("请后台先添加快递公司");
            } else {
                if (orderQueryVo.getPinkId() != null && orderQueryVo.getPinkId() > 0L) {
                    StorePink pink = (StorePink)this.pinkService.getById(orderQueryVo.getPinkId());
                    if (!OrderInfoEnum.PINK_STATUS_2.getValue().equals(pink.getStatus())) {
                        throw new EshopException("拼团未成功不能发货");
                    }
                }

                StoreOrder storeOrder = StoreOrder.builder().id(orderQueryVo.getId()).status(OrderInfoEnum.STATUS_1.getValue()).deliveryId(deliveryId).deliveryName(expressQueryVo.getName()).deliveryType(deliveryType).deliverySn(expressQueryVo.getCode()).build();
                this.yxStoreOrderMapper.updateById(storeOrder);
                this.orderStatusService.create(orderQueryVo.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(), "已发货 快递公司：" + expressQueryVo.getName() + "快递单号：" + deliveryId);
                TemplateBean templateBean = TemplateBean.builder().orderId(orderQueryVo.getOrderId()).deliveryId(deliveryId).deliveryName(expressQueryVo.getName()).uid(orderQueryVo.getUid()).templateType(TemplateListenEnum.TYPE_3.getValue()).build();
                this.publisher.publishEvent(new TemplateEvent(this, templateBean));
                String redisKey = String.valueOf(StrUtil.format("{}{}", new Object[]{"order:unconfirm:", orderQueryVo.getId()}));
                this.redisTemplate.opsForValue().set(redisKey, orderQueryVo.getOrderId(), 7L, TimeUnit.DAYS);
            }
        } else {
            throw new EshopException("订单状态错误");
        }
    }

    public StoreOrderQueryVo handleOrder(StoreOrderQueryVo order) {
        LambdaQueryWrapper<StoreOrderCartInfo> wrapper = new LambdaQueryWrapper();
        wrapper.eq(StoreOrderCartInfo::getOid, order.getId());
        List<StoreOrderCartInfo> cartInfos = this.orderCartInfoService.list(wrapper);
        List<StoreCartQueryVo> cartInfo = (List)cartInfos.stream().map((cart) -> {
            StoreCartQueryVo cartQueryVo = (StoreCartQueryVo) JSON.parseObject(cart.getCartInfo(), StoreCartQueryVo.class);
            cartQueryVo.setUnique(cart.getUnique());
            cartQueryVo.setIsReply(this.productReplyService.replyCount(cart.getUnique()));
            return cartQueryVo;
        }).collect( Collectors.toList());
        order.setCartInfo(cartInfo);
        StatusDto statusDTO = new StatusDto();
        if (OrderStatusEnum.STATUS_0.getValue().equals(order.getPaid())) {
            int offset = Integer.valueOf(String.valueOf(30L));
            Date time = DateUtil.offsetMinute(order.getCreateTime(), offset);
            statusDTO.setClassfy("nobuy");
            statusDTO.setMsg( StrUtil.format("请在{}前完成支付", new Object[]{DateUtil.formatDateTime(time)}));
            statusDTO.setType("0");
            statusDTO.setTitle("未支付");
        } else if (OrderInfoEnum.REFUND_STATUS_1.getValue().equals(order.getRefundStatus())) {
            statusDTO.setClassfy("state-sqtk");
            statusDTO.setMsg("商家审核中,请耐心等待");
            statusDTO.setType("-1");
            statusDTO.setTitle("申请退款中");
        } else if (OrderInfoEnum.REFUND_STATUS_2.getValue().equals(order.getRefundStatus())) {
            statusDTO.setClassfy("state-sqtk");
            statusDTO.setMsg("已为您退款,感谢您的支持");
            statusDTO.setType("-2");
            statusDTO.setTitle("已退款");
        } else if (OrderInfoEnum.STATUS_0.getValue().equals(order.getStatus())) {
            if (order.getPinkId() > 0L) {
                if (this.pinkService.pinkIngCount(order.getPinkId()) > 0) {
                    statusDTO.setClassfy("state-nfh");
                    statusDTO.setMsg("待其他人参加拼团");
                    statusDTO.setType("1");
                    statusDTO.setTitle("拼团中");
                } else {
                    statusDTO.setClassfy("state-nfh");
                    statusDTO.setMsg("商家未发货,请耐心等待");
                    statusDTO.setType("1");
                    statusDTO.setTitle("未发货");
                }
            } else if (OrderInfoEnum.SHIPPIING_TYPE_1.getValue().equals(order.getShippingType())) {
                statusDTO.setClassfy("state-nfh");
                statusDTO.setMsg("商家未发货,请耐心等待");
                statusDTO.setType("1");
                statusDTO.setTitle("未发货");
            } else {
                statusDTO.setClassfy("state-nfh");
                statusDTO.setMsg("待核销,请到核销点进行核销");
                statusDTO.setType("1");
                statusDTO.setTitle("待核销");
            }
        } else if (OrderInfoEnum.STATUS_1.getValue().equals(order.getStatus())) {
            statusDTO.setClassfy("state-ysh");
            statusDTO.setMsg("服务商已发货");
            statusDTO.setType("2");
            statusDTO.setTitle("待收货");
        } else if (OrderInfoEnum.STATUS_2.getValue().equals(order.getStatus())) {
            statusDTO.setClassfy("state-ypj");
            statusDTO.setMsg("已收货,快去评价一下吧");
            statusDTO.setType("3");
            statusDTO.setTitle("待评价");
        } else if (OrderInfoEnum.STATUS_3.getValue().equals(order.getStatus())) {
            statusDTO.setClassfy("state-ytk");
            statusDTO.setMsg("交易完成,感谢您的支持");
            statusDTO.setType("4");
            statusDTO.setTitle("交易完成");
        }

        if (PayTypeEnum.WEIXIN.getValue().equals(order.getPayType())) {
            statusDTO.setPayType("微信支付");
        } else if (PayTypeEnum.YUE.getValue().equals(order.getPayType())) {
            statusDTO.setPayType("余额支付");
        } else {
            statusDTO.setPayType("积分支付");
        }

        order.setStatusDto(statusDTO);
        return order;
    }

    public void orderComment(ShopUser user, String unique, String comment, String pics, String productScore, String serviceScore) {
        LambdaQueryWrapper<StoreOrderCartInfo> queryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<StoreOrderCartInfo> eq = queryWrapper.eq( StoreOrderCartInfo::getUnique, unique );
        StoreOrderCartInfo orderCartInfo = (StoreOrderCartInfo)this.storeOrderCartInfoService.getOne(eq);
        if (ObjectUtil.isEmpty(orderCartInfo)) {
            throw new EshopException("评价产品不存在");
        } else {
            LambdaQueryWrapper<StoreProductReply> storeProductWrapper = new LambdaQueryWrapper<>();
            LambdaQueryWrapper<StoreProductReply> eq1 = storeProductWrapper.eq( StoreProductReply::getOid, orderCartInfo.getOid() )
                    .eq( StoreProductReply::getProductId, orderCartInfo.getProductId() );
            int count = this.productReplyService.count(eq1);
            if (count > 0) {
                throw new EshopException("该产品已评价");
            } else {
                StoreProductReply storeProductReply = StoreProductReply.builder().uid(user.getUid()).oid(orderCartInfo.getOid()).productId(orderCartInfo.getProductId()).productScore(Integer.valueOf(productScore)).serviceScore(Integer.valueOf(serviceScore)).comment(comment).pics(pics).unique(unique).build();
                this.productReplyService.save(storeProductReply);
                int replyCount = this.productReplyService.count(storeProductWrapper.eq(StoreProductReply::getOid, orderCartInfo.getOid()));
                int cartCount = this.storeOrderCartInfoService.count(queryWrapper.eq(StoreOrderCartInfo::getOid, orderCartInfo.getOid()));
                if (replyCount == cartCount) {
                    StoreOrder storeOrder = new StoreOrder();
                    storeOrder.setStatus(OrderInfoEnum.STATUS_3.getValue());
                    storeOrder.setId(orderCartInfo.getOid());
                    this.yxStoreOrderMapper.updateById(storeOrder);
                }

                this.orderStatusService.create(orderCartInfo.getOid(), OrderLogEnum.EVAL_ORDER.getValue(), OrderLogEnum.EVAL_ORDER.getDesc());
            }
        }
    }


    public void takeOrder(String orderId, Long uid) {
        StoreOrderQueryVo order = this.getOrderInfo(orderId, uid);
        if (ObjectUtil.isNull(order)) {
            throw new EshopException("订单不存在");
        } else {
            order = this.handleOrder(order);

            if (!OrderStatusEnum.STATUS_2.getValue().toString().equals(order.getStatusDto())) {
                throw new BusinessException("订单状态错误");
            } else {
                StoreOrder storeOrder = new StoreOrder();
                storeOrder.setStatus(OrderInfoEnum.STATUS_2.getValue());
                storeOrder.setId(order.getId());
                this.yxStoreOrderMapper.updateById(storeOrder);
                this.orderStatusService.create(order.getId(), OrderLogEnum.TAKE_ORDER_DELIVERY.getValue(), OrderLogEnum.TAKE_ORDER_DELIVERY.getDesc());
                this.gainUserIntegral(order);
                this.userService.backOrderBrokerage(order);
            }
        }
    }

    public void yuePay(String orderId, Long uid) {
        StoreOrderQueryVo orderInfo = this.getOrderInfo(orderId, uid);
        if (ObjectUtil.isNull(orderInfo)) {
            throw new EshopException("订单不存在");
        } else if (OrderInfoEnum.PAY_STATUS_1.getValue().equals(orderInfo.getPaid())) {
            throw new EshopException("该订单已支付");
        } else {
            UserQueryVo userInfo = this.userService.getYxUserById(uid);
            if (userInfo.getNowMoney().compareTo(orderInfo.getPayPrice()) < 0) {
                throw new EshopException("余额不足");
            } else {
                this.userService.decPrice(uid, orderInfo.getPayPrice());
                this.paySuccess(orderInfo.getOrderId(), PayTypeEnum.YUE.getValue());
            }
        }
    }

    public void paySuccess(String orderId, String payType) {
        StoreOrderQueryVo orderInfo = this.getOrderInfo(orderId, (Long)null);
        LambdaQueryWrapper<StoreOrder> wrapper = new LambdaQueryWrapper();
        wrapper.eq(StoreOrder::getOrderId, orderId);
        StoreOrder storeOrder = new StoreOrder();
        storeOrder.setPaid(OrderInfoEnum.PAY_STATUS_1.getValue());
        storeOrder.setPayType(payType);
        storeOrder.setPayTime(new Date());
        this.yxStoreOrderMapper.update(storeOrder, wrapper);
        this.userService.incPayCount(orderInfo.getUid());
        this.orderStatusService.create(orderInfo.getId(), OrderLogEnum.PAY_ORDER_SUCCESS.getValue(), OrderLogEnum.PAY_ORDER_SUCCESS.getDesc());
        if (orderInfo.getCombinationId() > 0L) {
            this.pinkService.createPink(orderInfo);
        }

        if (orderInfo.getBargainId() > 0L) {
            this.storeBargainUserService.setBargainUserStatus(orderInfo.getBargainId(), orderInfo.getUid());
        }

        ShopUser userInfo = (ShopUser)this.userService.getById(orderInfo.getUid());
        String payTypeMsg = PayTypeEnum.WEIXIN.getDesc();
        if (PayTypeEnum.YUE.getValue().equals(payType)) {
            payTypeMsg = PayTypeEnum.YUE.getDesc();
        }

        this.billService.expend(userInfo.getUid(), "购买商品", BillDetailEnum.CATEGORY_1.getValue(), BillDetailEnum.TYPE_3.getValue(), orderInfo.getPayPrice().doubleValue(), userInfo.getNowMoney().doubleValue(), payTypeMsg + orderInfo.getPayPrice() + "元购买商品");
        TemplateBean templateBean = TemplateBean.builder().orderId(orderInfo.getOrderId()).price(orderInfo.getPayPrice().toString()).uid(orderInfo.getUid()).templateType(TemplateListenEnum.TYPE_1.getValue()).build();
        this.publisher.publishEvent(new TemplateEvent(this, templateBean));
    }


    private void gainUserIntegral(StoreOrderQueryVo order) {
        if (order.getGainIntegral().compareTo( BigDecimal.ZERO) > 0) {
            ShopUser user = (ShopUser)this.userService.getById(order.getUid());
            BigDecimal newIntegral = NumberUtil.add(user.getIntegral(), order.getGainIntegral());
            user.setIntegral(newIntegral);
            user.setUid(order.getUid());
            this.userService.updateById(user);
            this.billService.income(user.getUid(), "购买商品赠送积分", BillDetailEnum.CATEGORY_2.getValue(), BillDetailEnum.TYPE_9.getValue(), order.getGainIntegral().doubleValue(), newIntegral.doubleValue(), "购买商品赠送" + order.getGainIntegral() + "积分", order.getId().toString());
        }
    }

    public void removeOrder(String orderId, Long uid) {
        StoreOrderQueryVo order = this.getOrderInfo(orderId, uid);
        if (order == null) {
            throw new EshopException("订单不存在");
        } else {
            order = this.handleOrder(order);
            if (!OrderInfoEnum.STATUS_3.getValue().equals(order.getStatus())) {
                throw new EshopException("该订单无法删除");
            } else {
                this.yxStoreOrderMapper.deleteById(order.getId());
                this.orderStatusService.create(order.getId(), OrderLogEnum.REMOVE_ORDER.getValue(), OrderLogEnum.REMOVE_ORDER.getDesc());
            }
        }
    }
}
